import FileSaver from 'file-saver';
import request from './request';

interface FileProps {
  id?: string;
  url?: string;
  fileName?: string;
  serviceId?: string;
  type?: 'blob' | 'arrayBuffer';
  changeId?: string;
  allLogData?: object;
}
export async function uploadFileApi(params: any) {
  return request('/file/upload', {
    method: 'POST',
    data: params,
    serviceId: 'fwFile',
  });
}

/**
 * 文件对象转base64
 *
 * @param {File} file
 * @return {*}
 */
export const file2Base64 = function (file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    try {
      const reader = new FileReader();
      reader.onload = function (e: any) {
        const res: string = e.target.result;
        resolve(res);
      };
      reader.readAsDataURL(file);
    } catch (error) {
      reject(error);
    }
  });
};

//base64转blob
export const base642Blob = function (dataURI: string) {
  const byteString = atob(dataURI.split(',')[1]);
  const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  const ab = new ArrayBuffer(byteString.length);
  const ia = new Uint8Array(ab);
  for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], { type: mimeString });
};

//上传图片
export const uploadFile = async (file: File) => {
  const { name: fileName } = file;
  const base64 = await file2Base64(file);
  const blob = base642Blob(base64);
  const body = new FormData();
  body.append(fileName, blob);
  //把请求相关参数放入formData中
  body.append('tempFile', 'false');
  body.append('recTypeId', '0');
  body.append('recId', '0');
  body.append('subRecTypeId', '0');
  body.append('subRecId', '0');
  const ret = await uploadFileApi(body);
  return ret;
};

/**
 *下载文件，包括框架上的下载文件和业务上的下载文件
 *
 * @export
 * @param {{ id: string; url?: string; fileName?: string }}
 */
export async function downloadFile({
  id,
  url = '/file/downloadFile',
  fileName = '',
  serviceId = '',
  allLogData = {},
}: FileProps) {
  const response = await request(
    url,
    {
      method: 'POST',
      data: id ? { id } : { ...allLogData },
      serviceId: serviceId,
      responseType: 'blob',
    },
    {
      isStream: true,
    },
  );

  const finalFileName = fileName || response.headers.get('content-disposition').split('filename=')[1] || 'download.txt';
  const blob = await response.blob();
  return FileSaver(blob, decodeURI(finalFileName));
}

export async function newDownloadFile({ url = '/file/downloadFile', serviceId, fileName, ...rest }: FileProps) {
  const response = await request(
    url,
    {
      method: 'POST',
      data: { ...rest },
      serviceId: serviceId,
      responseType: 'blob',
    },
    {
      isStream: true,
    },
  );

  const finalFileName = fileName || response.headers.get('content-disposition').split('filename=')[1] || 'download.txt';
  const blob = await response.blob();
  return FileSaver(blob, decodeURI(finalFileName));
}
/**
 *获取文件二进制流或原始数据对象
 *
 * @export
 * @param {{ id: string; url?: string; fileName?: string }} { id, url = '/file/downloadFile', fileName = 'download' }
 */
export async function getFileByType({ id, url = '/file/previewFile.api', type = 'arrayBuffer' }: FileProps) {
  if (!id) {
    console.error('没有传入id');
    return;
  }
  const response = await request(
    `/fwFile${url}?id=${id}`,
    {
      method: 'POST',
      responseType: type,
      suffix: '',
    },
    {
      isStream: true,
    },
  );
  const result = await response[type]();
  return result;
}

/**
 *
 *blob 转buffer
 * @param {Blob} blob
 * @return {*}
 */
export const blob2Buffer = function (blob: Blob) {
  return new Promise((resolve, reject) => {
    try {
      const reader = new FileReader();
      reader.onload = function (e: any) {
        resolve(e.target.result);
      };
      reader.readAsArrayBuffer(blob);
    } catch (error) {
      reject(error);
    }
  });
};

//buffer转blob
export const buffer2Blob = function (buffer: Buffer) {
  const blob = new Blob([buffer]);
  return blob;
};

/**
 * base64转file
 *
 * @param {string} urlData
 * @param {string} filename
 * @return {*}
 */
export const base642File = function (urlData: string) {
  if (typeof urlData != 'string') {
    console.error('urlData不是字符串');
    return;
  }
  const arr: any[] = urlData.split(',');
  const type = arr[0].match(/:(.*?);/)[1];
  const fileExt = type.split('/')[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], 'filename.' + fileExt, {
    type: type,
  });
};

/**
 * blob 转 文本
 * @param blob
 * @returns
 */
export function blob2Text(blob: Blob) {
  return new Promise((resolve, reject) => {
    try {
      const reader = new FileReader();
      reader.onload = (e) => {
        resolve(e?.target?.result);
      };
      reader.readAsText(blob);
    } catch (error) {
      reject(error);
    }
  });
}

/**
 *  blob转File
 *
 * @export
 * @param {Blob} blob
 * @param {string} [filename='文件']
 * @param {string} [type='text/plain']
 * @return {*}
 */
export function blob2File(blob: Blob, filename = '文件') {
  const type = blob.type;
  const files = new window.File([blob], filename, { type });
  return files;
}
